include(FetchContent)

function(_setup_folly)
  # 名称
  set(PNAME folly)

  # Exclude exception tracer, which is necessary to statically link libstdc++
  # std::unexpected_handler和std::set_unexpected_handler已经在cxx17后被移除,
  # 但folly/experimental/exception_tracer/ExceptionTracer.cpp中仍然使用了, 所以需要禁用
  set(FOLLY_NO_EXCEPTION_TRACER 1)
  # 和folly一致,临时设置为17
  set(CMAKE_CXX_STANDARD 17)
  set(CMAKE_CXX_STANDARD_REQUIRED ON)

  set(CMAKE_LIBRARY_ARCHITECTURE x86_64)
  # 动态库生成位置无关的代码(Position-Independent-Code)
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)

  if(WIN32)
    # set(MSVC_LANGUAGE_VERSION "c++latest" CACHE STRING "设置为'c++17'或'c++latest'. 覆盖FollyCompilerMSVC.cmake中对应项目." FORCE)
    set(CMAKE_DISABLE_FIND_PACKAGE_LibDwarf ON CACHE INTERNAL "不使用LibDwarf")
    set(CMAKE_DISABLE_FIND_PACKAGE_Libiberty ON CACHE INTERNAL "不使用Libiberty")
    set(CMAKE_DISABLE_FIND_PACKAGE_LibAIO ON CACHE INTERNAL "不使用LibAIO")
    set(CMAKE_DISABLE_FIND_PACKAGE_LibUring ON CACHE INTERNAL "不使用LibUring")
    set(CMAKE_DISABLE_FIND_PACKAGE_Libsodium ON CACHE INTERNAL "不使用Libsodium")
    set(CMAKE_DISABLE_FIND_PACKAGE_LibUnwind ON CACHE INTERNAL "不使用LibUnwind")
    set(CMAKE_DISABLE_FIND_PACKAGE_Backtrace ON CACHE INTERNAL "不使用Backtrace")
  endif()
  #  set(CMAKE_CXX_FLAGS "-march=native" CACHE STRING "CXX Flags" FORCE)

  message(STATUS "Use CMAKE_CXX_STANDARD: " ${CMAKE_CXX_STANDARD})

  # 禁用coro
  # add_definitions(-DFOLLY_CFG_NO_COROUTINES)

  # 消除MSVC下编译folly时的警告
  if(MSVC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4855 /wd4242 /wd4244 /wd4245 /wd4250 /wd4267 /wd4319 /wd4437 /wd4468 /wd5243 /wd5041 /wd4700 /wd4866 /wd5054 /wd5219 /wd5204 /wd5220 /wd5245 /wd5246")
    add_definitions(-DNOMINMAX)
    # 需要定义在including logging.h之前
    add_definitions(-DGLOG_NO_ABBREVIATED_SEVERITIES)
  endif()

  # 补丁命令
  if(UNIX)
    set(PATCH_COMMAND1
      ${CMAKE_COMMAND} -E env bash -c "sed -i 's/VERSION 3.0.2 FATAL_ERROR/VERSION 3.5 FATAL_ERROR/' ${CMAKE_BINARY_DIR}/_deps/folly-src/CMakeLists.txt")
  else()
    set(PATCH_COMMAND1 ${CMAKE_COMMAND} -E echo "Patch done")
  endif()

  # 下载
  FetchContent_Declare(
    folly
    URL file://${CMAKE_SOURCE_DIR}/download/folly-v2024.07.01.00.tar.gz
    URL_HASH SHA256=e78584ab7ba9a687285f2849bc0141e2422a5c808ad6ab3558c83d85975e25ed
    #    GIT_REPOSITORY https://gitee.com/mirrors/folly.git
    #    GIT_TAG v2024.06.24.00
    #    UPDATE_COMMAND ""
    #    UPDATE_DISCONNECTED 1
    PATCH_COMMAND
    # 在40-60行间搜索和替换
    sed -i "40,60s/find_package(DoubleConversion MODULE REQUIRED)/find_package(double-conversion CONFIG REQUIRED)/" CMake/folly-deps.cmake
  )
  # Now, ${folly_SOURCE_DIR} is set to something like D:/workspace/tradev-cpp/build/Debug/_deps/folly-src

  FetchContent_MakeAvailable(folly)

  # 这是编译folly时需要用到的私有FLAGS
  target_compile_options(folly_base PRIVATE
    $<$<CXX_COMPILER_ID:GNU>:
    -Wno-deprecated-declarations
    -Wno-stringop-overread
    -Wno-overloaded-virtual
    -Wno-uninitialized
    -Wno-address
    -Wno-unused-result
    -Wno-nonnull-compare
    -Wno-return-type
    -Wno-redundant-move
    -Wno-nonnull>
    $<$<CXX_COMPILER_ID:Clang>:
    -Wno-nullability-completeness>)
  target_compile_options(folly PUBLIC
    $<$<CXX_COMPILER_ID:GNU>:
    -Wno-deprecated-declarations>)

  #  message(STATUS "folly_POPULATED: " ${folly_POPULATED})
  message(STATUS "folly_SOURCE_DIR: " ${folly_SOURCE_DIR})
  message(STATUS "folly_BINARY_DIR: " ${folly_BINARY_DIR})

  # 设置folly-config.cmake目录
  #	set(folly_DIR ${folly_BINARY_DIR} PARENT_SCOPE)
  #	message(STATUS "folly_DIR: " ${folly_DIR})

  # 和VCPKG保持一致
  add_library(Folly::folly ALIAS folly)
  add_library(Folly::folly_deps ALIAS folly_deps)
  add_library(Folly::follybenchmark ALIAS follybenchmark)
endfunction()

################################################################################
# 安装dolphindb-cxx-api
function(_setup_dolphindb_cxx_api)
  set(PNAME dolphindbapi)
  #  find_package(OpenSSL REQUIRED)
  FetchContent_Declare(${PNAME}
    GIT_REPOSITORY https://gitee.com/dolphindb/api-cplusplus.git
    GIT_TAG main
    # 补定制作可使用patchf命令
    # 或者diff -ruN CMakeLists.txt CMakeLists.txt.new > dolphindb_00_cmake_min_version.patch
    # PATCH_COMMAND git apply ${CMAKE_SOURCE_DIR}/patch/dolphindb_cxx_api_10_SysIO.patch
    UPDATE_DISCONNECTED 1 # 禁止更新
    GIT_SHALLOW ON)
  FetchContent_MakeAvailable(${PNAME})

  # 使用dolphindbapi自带的ssl库
  if(WIN32)
    set(SSL_LIBS ${dolphindbapi_SOURCE_DIR}/bin/vs2017_x64 CACHE PATH "dolphindbapi ssl libs")
  endif()

  # 定义预编译宏(-DXXX)
  target_compile_definitions(DolphinDBAPI
    PUBLIC
    $<$<PLATFORM_ID:Windows>:WINDOWS;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NOMINMAX;>
    $<$<PLATFORM_ID:Linux>:LINUX;_GLIBCXX_USE_CXX11_ABI=1>
    PRIVATE
    $<$<PLATFORM_ID:Windows>:NDEBUG;CPPAPI_EXPORTS;_DDBAPIDLL;>)

  target_compile_options(DolphinDBAPI PRIVATE
    $<$<PLATFORM_ID:Linux>:
    -Wno-class-memaccess
    -Wno-header-guard
    -Wno-unqualified-std-cast-call
    -Wno-mismatched-tags
    -Wno-unused-private-field
    -Wno-inconsistent-missing-override
    -Wno-implicit-const-int-float-conversion
    -Wno-tautological-constant-out-of-range-compare
    -Wno-return-type
    -Wno-empty-body
    -Wno-string-plus-int
    -Wno-pessimizing-move
    -Wno-deprecated-declarations
    -Wno-misleading-indentation
    -Wno-deprecated-register
    -Wno-overloaded-virtual>)

  target_include_directories(DolphinDBAPI
    PUBLIC
    $<$<PLATFORM_ID:Windows>:${SSL_LIBS}/include64>
    ${dolphindbapi_SOURCE_DIR}/include)
  target_link_directories(DolphinDBAPI
    PUBLIC
    ${dolphindbapi_BINARY_DIR})

  # 拷贝dll到可执行文件目录
  if(WIN32)
    # file(COPY_FILE ${SSL_LIBS}/lib64/libeay32MD.dll ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libeay32MD.dll ONLY_IF_DIFFERENT)
    # file(COPY_FILE ${SSL_LIBS}/lib64/ssleay32MD.dll ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ssleay32MD.dll ONLY_IF_DIFFERENT)
  endif()
endfunction()

################################################################################
# 华锐AMA
function(_setup_amdama)
  set(PNAME ama)
  # 编译选项设置

  # 下载
  FetchContent_Declare(${PNAME}
    GIT_REPOSITORY http://gite.idoson.com/cgws/AmdAma.git
    GIT_TAG v4.0.1
    UPDATE_DISCONNECTED 1 # 禁止更新
    GIT_SHALLOW ON)
  FetchContent_MakeAvailable(${PNAME})

  message(STATUS "ama_SOURCE_DIR: " ${ama_SOURCE_DIR})
  message(STATUS "ama_BINARY_DIR: " ${ama_BINARY_DIR})

  # 判断操作系统
  if(LINUX)
    set(ama_INCLUDE_DIR ${ama_SOURCE_DIR}/gentoo/c++/include CACHE PATH "ama include dir")
    set(ama_LIBRARY_DIR ${ama_SOURCE_DIR}/gentoo/c++/lib CACHE PATH "ama library dir")
    # 遍历目录,获取所有so文件
    file(GLOB AMA_API_LIBS "${ama_LIBRARY_DIR}/*.so*")
  else()
    set(ama_INCLUDE_DIR ${ama_SOURCE_DIR}/win/c++/include CACHE PATH "ama include dir")
    set(ama_LIBRARY_DIR ${ama_SOURCE_DIR}/win/c++/lib CACHE PATH "ama include dir")
    file(GLOB AMA_API_LIBS "${ama_LIBRARY_DIR}/*.lib*")
  endif()

  # 定义接口项目
  add_library(ama-deps INTERFACE)
  target_include_directories(ama-deps INTERFACE ${ama_INCLUDE_DIR})
  target_link_directories(ama-deps INTERFACE ${ama_LIBRARY_DIR})
  if(UNIX)
    target_link_options(ama-deps INTERFACE -Wl,-rpath='${ama_LIBRARY_DIR}')
  elseif(MSVC)
    target_compile_options(ama-deps INTERFACE /source-charset:utf-8 /execution-charset:utf-8)
  endif()
  target_link_libraries(ama-deps INTERFACE ${AMA_API_LIBS})
endfunction()
